/**
 * 
 */
package com.aspire.wap.core.log;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * 定义Log的级别 <code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>,
 * <code>WARN</code>, <code>INFO</code, <code>DEBUG</code>.
 *
 *
 * @author x_huyunan 2007-9-12 上午09:45:37
 * @version 1.0
 * @deprecated
 */

public class Level implements Serializable {

    /**
     * Serialization version id.
     */
    static final long serialVersionUID = 6491141966387921666L;

    /** log 级别 */
    transient int level;

    /** log 级别描述 */
    transient String levelStr;

    /** 相应的系统log */
    transient int syslogEquivalent;

    public final static int FATAL_INT = 50000;

    public final static int ERROR_INT = 40000;

    public final static int WARN_INT = 30000;

    public final static int INFO_INT = 20000;

    public final static int DEBUG_INT = 10000;

    public static final int TRACE_INT = 5000;

    public final static int ALL_INT = Integer.MIN_VALUE;

    /**
     * The <code>FATAL</code> level designates very severe error events that
     * will presumably lead the application to abort.
     */
    final static public Level FATAL = new Level(FATAL_INT, "FATAL", 0);

    /**
     * The <code>ERROR</code> level designates error events that might still
     * allow the application to continue running.
     */
    final static public Level ERROR = new Level(ERROR_INT, "ERROR", 3);

    /**
     * The <code>WARN</code> level designates potentially harmful situations.
     */
    final static public Level WARN = new Level(WARN_INT, "WARN", 4);

    /**
     * The <code>INFO</code> level designates informational messages that
     * highlight the progress of the application at coarse-grained level.
     */
    final static public Level INFO = new Level(INFO_INT, "INFO", 6);

    /**
     * The <code>DEBUG</code> Level designates fine-grained informational
     * events that are most useful to debug an application.
     */
    final static public Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7);

    /**
     * The <code>TRACE</code> Level designates finer-grained informational
     * events than the <code>DEBUG</code> level.
     */
    public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7);

    protected Level()
    {

    }

    /** 实例化 */
    protected Level(int level, String levelStr, int syslogEquivalent)
    {
        this.level = level;
        this.levelStr = levelStr;
        this.syslogEquivalent = syslogEquivalent;
    }

    /**
     * Convert the string passed as argument to a level. If the conversion
     * fails, then this method returns {@link #DEBUG}.
     */
    public static Level toLevel(String sArg)
    {
        return (Level) toLevel(sArg, Level.DEBUG);
    }

    /**
     * Convert an integer passed as argument to a level. If the conversion
     * fails, then this method returns {@link #DEBUG}.
     * 
     */
    public static Level toLevel(int val)
    {
        return (Level) toLevel(val, Level.DEBUG);
    }

    /**
     * Convert an integer passed as argument to a level. If the conversion
     * fails, then this method returns the specified default.
     */
    public static Level toLevel(int val, Level defaultLevel)
    {
        switch (val)
        {
            case DEBUG_INT:
                return Level.DEBUG;
            case INFO_INT:
                return Level.INFO;
            case WARN_INT:
                return Level.WARN;
            case ERROR_INT:
                return Level.ERROR;
            case FATAL_INT:
                return Level.FATAL;
            case TRACE_INT:
                return Level.TRACE;
            default:
                return defaultLevel;
        }
    }

    /**
     * Convert the string passed as argument to a level. If the conversion
     * fails, then this method returns the value of <code>defaultLevel</code>.
     */
    public static Level toLevel(String sArg, Level defaultLevel)
    {
        if (sArg == null)
        {
            return defaultLevel;
        }

        String s = sArg.toUpperCase();

        if (s.equals("DEBUG"))
        {
            return Level.DEBUG;
        }
        if (s.equals("INFO"))
        {
            return Level.INFO;
        }
        if (s.equals("WARN"))
        {
            return Level.WARN;
        }
        if (s.equals("ERROR"))
        {
            return Level.ERROR;
        }
        if (s.equals("FATAL"))
        {
            return Level.FATAL;
        }
        if (s.equals("TRACE"))
        {
            return Level.TRACE;
        }
        return defaultLevel;
    }

    /**
     * Custom deserialization of Level.
     * 
     * @param s
     *            serialization stream.
     * @throws IOException
     *             if IO exception.
     * @throws ClassNotFoundException
     *             if class not found.
     */
    private void readObject(final ObjectInputStream s) throws IOException,
            ClassNotFoundException
    {
        s.defaultReadObject();
        level = s.readInt();
        syslogEquivalent = s.readInt();
        levelStr = s.readUTF();
        if (levelStr == null)
        {
            levelStr = "";
        }
    }

    /**
     * Serialize level.
     * 
     * @param s
     *            serialization stream.
     * @throws IOException
     *             if exception during serialization.
     */
    private void writeObject(final ObjectOutputStream s) throws IOException
    {
        s.defaultWriteObject();
        s.writeInt(level);
        s.writeInt(syslogEquivalent);
        s.writeUTF(levelStr);
    }

    /**
     * Resolved deserialized level to one of the stock instances. May be
     * overriden in classes derived from Level.
     * 
     * @return resolved object.
     * @throws ObjectStreamException
     *             if exception during resolution.
     */
    private Object readResolve() throws ObjectStreamException
    {
        //
        // if the deserizalized object is exactly an instance of Level
        //
        if (getClass() == Level.class)
        {
            return toLevel(level);
        }
        //
        // extension of Level can't substitute stock item
        //
        return this;
    }

    /**
     * Return the syslog equivalent of this priority as an integer.
     */
    public final int getSyslogEquivalent()
    {
        return syslogEquivalent;
    }

    /**
     * Returns <code>true</code> if this level has a higher or equal level
     * than the level passed as argument, <code>false</code> otherwise.
     * 
     * <p>
     * You should think twice before overriding the default implementation of
     * <code>isGreaterOrEqual</code> method.
     * 
     */
    public boolean isGreaterOrEqual(Level l)
    {
        return level >= l.level;
    }

    /** 比较等级是否相等 */
    public boolean equals(Object o)
    {
        if (o instanceof Level)
        {
            Level l = (Level) o;
            return (this.level == l.level);
        }
        else
        {
            return false;
        }
    }

    /**
     * Returns the string representation of this priority.
     */
    final public String toString()
    {
        return levelStr;
    }

    /**
     * Returns the integer representation of this level.
     */
    public final int toInt()
    {
        return level;
    }

}